#include "tools/embed_manifest.h"



/**
 * @brief 将清单文件嵌入到可执行文件中
 * 
 * @param executablePath 目标可执行文件路径
 * @param manifestPath   清单文件路径
 * @param resourceId     资源ID (应用程序通常用1，DLL用2)
 * @return int           操作结果状态码
 */
int _EmbedManifest(const char* executablePath, 
                 const char* manifestPath, 
                 int resourceId) {
    // 参数验证
    if (!executablePath || !manifestPath || resourceId <= 0) {
        return EMBED_INVALID_PARAMETER;
    }

    // 读取清单文件内容
    FILE* manifestFile = fopen(manifestPath, "rb");
    if (!manifestFile) {
        return EMBED_FILE_OPEN_ERROR;
    }

    fseek(manifestFile, 0, SEEK_END);
    long manifestSize = ftell(manifestFile);
    fseek(manifestFile, 0, SEEK_SET);

    BYTE* manifestData = (BYTE*)malloc(manifestSize);
    if (!manifestData) {
        fclose(manifestFile);
        return EMBED_FILE_READ_ERROR;
    }

    if (fread(manifestData, 1, manifestSize, manifestFile) != manifestSize) {
        free(manifestData);
        fclose(manifestFile);
        return EMBED_FILE_READ_ERROR;
    }
    fclose(manifestFile);

    // 打开目标可执行文件进行资源更新
    HANDLE hUpdate = BeginUpdateResourceA(executablePath, FALSE);
    if (!hUpdate) {
        free(manifestData);
        return GetLastError() == ERROR_FILE_NOT_FOUND ? 
               EMBED_FILE_OPEN_ERROR : EMBED_RESOURCE_UPDATE_ERROR;
    }

    // 更新清单资源
    BOOL result = UpdateResourceA(
        hUpdate,                   // 更新句柄
        RT_MANIFEST,               // 资源类型: 清单
        MAKEINTRESOURCEA(resourceId), // 资源ID
        MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), // 语言: 中性
        manifestData,              // 清单数据
        manifestSize               // 数据大小
    );

    free(manifestData);
    
    if (!result) {
        EndUpdateResourceA(hUpdate, TRUE); // 放弃更改
        return EMBED_RESOURCE_UPDATE_ERROR;
    }

    // 提交更改
    if (!EndUpdateResourceA(hUpdate, FALSE)) {
        return EMBED_RESOURCE_UPDATE_ERROR;
    }

    return EMBED_SUCCESS;
}
